package logic.common.team;

import java.util.Collection;

import com.jme.math.Vector3f;

import logic.common.team.processes.DroneProcess;
import logic.common.team.processes.ProcessAddEvent;
import logic.common.team.processes.ProcessFinishEvent;
import logic.common.team.processes.ProcessStartEvent;
import logic.common.team.processes.TeamProcessListener;
import logic.ships.drone.Drone;
import map.asteroids.AsteroidField;

public class DronesAction extends TeamAction {
	
	private int pendingDrones;
	
	public DronesAction(Team team) {
		super(team);
		
		team.addTeamProcessListener(new TeamProcessListener() {
			@Override
			public void processFinished(ProcessFinishEvent event) {
				if(event.getTeamProcess() instanceof DroneProcess) pendingDrones--;
			}
			
			@Override
			public void processStarted(ProcessStartEvent event) {}
			@Override
			public void processAdded(ProcessAddEvent event) {}
		});
	}
	
	@Override
	public void performAction() {
		if(newDroneNecessary()) {
			team.spendTeamMoney(team.getDroneProperties().getCosts());
			team.addTeamProcess(new DroneProcess(team));
			pendingDrones++;
		}
		
		Collection<AsteroidField> fields = team.getHarvestableAsteroidFields();
		if(fields.isEmpty()) return;
		
		for(Drone drone : team.getDrones()) {
			if(drone.getCurrentAsteroid() == null) {
				AsteroidField nextField = getNearestField(drone, fields);
				
				if(nextField != null) drone.harvestAsteroid(nextField.getNextResourceAsteroid());
			}
		}
	}
	
	protected AsteroidField getNearestField(Drone drone, Collection<AsteroidField> fields) {
		AsteroidField nextField = null;
		float minDist = Float.POSITIVE_INFINITY;
		
		for(AsteroidField field : fields) {
			if(field.getClearAsteroids() < field.getAsteroids().size() / 3 * 2) continue;
			
			Vector3f fieldCenter = field.getProperties().getCenter();
			float dist = fieldCenter.distance(drone.getLocalTranslation());
			if(dist < minDist) {
				nextField = field;
				minDist = dist;
			}
		}
		
		return nextField;
	}
	
	protected boolean newDroneNecessary() {
		if(team.getTeamMoney() < team.getDroneProperties().getCosts()) return false;
		
		int freeAsteroids = 0;
		for(AsteroidField field : team.getHarvestableAsteroidFields()) {
			freeAsteroids += field.getClearAsteroids() / 2;
		}
		
		return freeAsteroids > team.getDrones().size() + pendingDrones;
	}
}